package org.ifilm.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;


import org.ifilm.model.User;
import org.ifilm.model.UserRating;
import org.springframework.stereotype.Repository;

/**
 * 
 * @author Mustafa Genç
 *
 */
@Repository
public class UserDaoImpl implements UserDao {
	@PersistenceContext
	private EntityManager entityManager;

	@Override
	public User createUser(User user) {
		return entityManager.merge(user);
	}
	
	@Override
	public UserRating createUserRating(UserRating userRating) {
		return entityManager.merge(userRating);
	}

	@Override
	public User getUser(String email, String password) {
		try {
			Query query = entityManager.createQuery(getUserQuery());
			query.setParameter("email", email);
			query.setParameter("password", password);

			return (User) query.getSingleResult();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private String getUserQuery() {
		StringBuilder strBuild = new StringBuilder();
		strBuild.append("select u from user u left join fetch u.followingUsers where (u.email=:email) and (u.password=:password)");
		return strBuild.toString();
	}
	
	@Override
	public User getUserById(Long id) {
		try {
			Query query = entityManager.createQuery(getUserByIdQuery());
			query.setParameter("id", id);

			return (User) query.getSingleResult();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	private String getUserByIdQuery() {
		StringBuilder strBuild = new StringBuilder();
		strBuild.append("select u from user u where u.id=:id");
		return strBuild.toString();
	}
	

	@Override
	public List<User> getAllUsers() {
		try {
			Query query = entityManager.createQuery(getAllUsersQuery());
			return (List<User>)query.getResultList();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private String getAllUsersQuery() {
		StringBuilder strBuild = new StringBuilder();
		// this method returns a list consisting of all users in the database
		strBuild.append("select u from user u");
		return strBuild.toString();
	}
	
	@Override
	public void editUser(User user){
		entityManager.merge(user);
	}
	
	@Override
	public UserRating getUserRate(Long userId, User rater) {
		try {
			Query query = entityManager.createQuery(getUserRateQuery());
			query.setParameter("rater", rater);
			query.setParameter("userId", userId);
			return (UserRating)query.getSingleResult();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	private String getUserRateQuery() {
		StringBuilder strBuild = new StringBuilder();
		strBuild.append("select p from userrating p where p.rater=:rater and p.ratedUser.id=:userId");
		return strBuild.toString();
	}
}